﻿using Common.AspNetCore;
using File.Api.Models;
using File.Api.Service;
using File.Api.Utils;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.IO;
using System.Linq;

namespace File.Api.Controllers
{
    [Route("api/LSExcel")]
    public class LSExcelController : ApiController
    {
        private readonly PdfService pdfService;

        public LSExcelController(IServiceProvider provider, PdfService pdfService)
           : base(provider)
        {
            this.pdfService = pdfService;
        }

        /// <summary>
        /// 监装报表导出
        /// </summary>
        /// <param name="orderModel"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost, Route("ExportLSOrderExcel")]
        public ActionResult ExportLSOrderExcel([FromBody] LSOrderModel orderModel)
        {
            if (!orderModel.Items.Any())
            {
                return null;
            }

            IWorkbook workbook = new XSSFWorkbook();
            ISheet sheet = workbook.CreateSheet();
            GenerateSheetSetColunmsWidth(sheet);
            int rowNum = 0;
            GenerateExcelLSHeader(workbook, sheet, rowNum, "监装检验报表");
            rowNum += 1;
            GenerateSheetLSHeader(workbook, sheet, rowNum, orderModel);
            rowNum += 9;
            orderModel.Items.ForEach(o =>
            {
                AddLSItemRow(workbook, sheet, rowNum, o);
                rowNum++;
            });

            var footModel = new ContainerCheckOrderModel()
            {
                CheckUser = orderModel.CheckUser,
                ResponsibleUser = orderModel.AuditUser,
                ShelfLife = orderModel.ShelfLife,
                TableCode = orderModel.TableCode,
            };

            GenerateSheetLSFooter(workbook, sheet, rowNum, footModel);

            if (orderModel.Type == 0)
            {
                using (var ms = new MemoryStream())
                {
                    workbook.Write(ms, false);
                    var name = $"{orderModel.SamplingSchemeName}_{DateTime.Now}.xlsx";
                    return File(ms.ToArray(), "application/octet-stream", name);
                }
            }

            using (var ms = new MemoryStream())
            {
                workbook.Write(ms, false);
                var name = $"{orderModel.SamplingSchemeName}_{DateTime.Now}.pdf";
                return File(pdfService.Render(ms.ToArray()), "application/octet-stream", name);
            }
        }

        /// <summary>
        /// 监装报表导出
        /// </summary>
        /// <param name="orderModel"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost, Route("ExportLSContainerOrderExcel")]
        public ActionResult ExportLSContainerOrderExcel([FromBody] ContainerCheckOrderModel orderModel)
        {
            if (!orderModel.Items.Any())
            {
                return null;
            }

            IWorkbook workbook = new XSSFWorkbook();
            ISheet sheet = workbook.CreateSheet();
            GenerateSheetSetColunmsWidth(sheet);
            int rowNum = 0;
            GenerateExcelLSHeader(workbook, sheet, rowNum, "货柜七点检查表");
            rowNum += 1;
            GenerateSheetContainerCheckHeader(workbook, sheet, rowNum, orderModel);
            rowNum += 3;
            orderModel.Items.ForEach(o =>
            {
                AddContainerCheckItemRow(workbook, sheet, rowNum, o);
                rowNum++;
            });

            GenerateSheetLSFooter(workbook, sheet, rowNum, orderModel);

            if (orderModel.Type == 0)
            {
                using (var ms = new MemoryStream())
                {
                    workbook.Write(ms, false);
                    var name = $"货柜七点检查_{orderModel.ContainerCode}_{DateTime.Now}.xlsx";
                    return File(ms.ToArray(), "application/octet-stream", name);
                }
            }

            using (var ms = new MemoryStream())
            {
                workbook.Write(ms, false);
                var name = $"货柜七点检查_{orderModel.ContainerCode}_{DateTime.Now}.pdf";
                return File(pdfService.Render(ms.ToArray()), "application/octet-stream", name);
            }
        }

        /// <summary>
        /// 监装明细
        /// </summary>
        /// <param name="batchItem"></param>
        /// <param name="workbook"></param>
        /// <param name="sheet"></param>
        /// <param name="rowNum"></param>
        private void AddLSItemRow(IWorkbook workbook, ISheet sheet, int rowNum, LSOrderSamplingSchemeItemModel item)
        {
            IRow headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue(item.Index);
            headerRow.CreateCell(1, CellType.String).SetCellValue(item.Name);
            headerRow.CreateCell(3, CellType.String).SetCellValue(item.ResultReferenceValue);
            headerRow.CreateCell(4, CellType.String).SetCellValue(item.StrResult);
            headerRow.CreateCell(5, CellType.String).SetCellValue(item.Remark);
            MergedRegion(sheet, rowNum, rowNum, 1, 2, workbook);
            ExcelStyleUtils.SetRowWrapText(workbook, headerRow);
        }

        /// <summary>
        /// 货柜七点明细
        /// </summary>
        /// <param name="batchItem"></param>
        /// <param name="workbook"></param>
        /// <param name="sheet"></param>
        /// <param name="rowNum"></param>
        private void AddContainerCheckItemRow(IWorkbook workbook, ISheet sheet, int rowNum, ContainerCheckOrderItemModel item)
        {
            IRow headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue(item.Name);
            headerRow.CreateCell(1, CellType.String).SetCellValue(item.Content);
            headerRow.CreateCell(5, CellType.String).SetCellValue(item.StrResult);
            MergedRegion(sheet, rowNum, rowNum, 1, 4, workbook);
            ExcelStyleUtils.SetRowWrapText(workbook, headerRow);
        }

        /// <summary>
        /// 监装表头
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheet"></param>
        /// <param name="rowNum"></param>
        /// <param name="orderModel"></param>
        private void GenerateSheetLSHeader(IWorkbook workbook, ISheet sheet, int rowNum, LSOrderModel orderModel)
        {
            ICellStyle boldStyle = ExcelStyleUtils.GetExcelOQCStyle(workbook);
            IRow headerRow = sheet.CreateRow(rowNum);
            var saleCode = string.Empty;
            headerRow.CreateCell(0, CellType.String).SetCellValue("监装日期");
            headerRow.CreateCell(1, CellType.String).SetCellValue(orderModel.StrCreateTime);
            headerRow.CreateCell(2, CellType.String).SetCellValue("装柜编号+分组");
            headerRow.CreateCell(3, CellType.String).SetCellValue(orderModel.ContainerNumber);
            headerRow.CreateCell(4, CellType.String).SetCellValue("客户简称");
            headerRow.CreateCell(5, CellType.String).SetCellValue(orderModel.Customer);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("检验批号");
            headerRow.CreateCell(1, CellType.String).SetCellValue(orderModel.Code);
            headerRow.CreateCell(2, CellType.String).SetCellValue("柜号");
            headerRow.CreateCell(3, CellType.String).SetCellValue(orderModel.ContainerCode);
            headerRow.CreateCell(4, CellType.String).SetCellValue("锁号");
            headerRow.CreateCell(5, CellType.String).SetCellValue(orderModel.LockCode);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });
            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("实际出货数量");
            headerRow.CreateCell(1, CellType.String).SetCellValue(orderModel.RealityShipmentQty.ToString());
            headerRow.CreateCell(2, CellType.String).SetCellValue("外向交货单号");
            headerRow.CreateCell(3, CellType.String).SetCellValue(orderModel.OutboundDelivery);
            MergedRegion(sheet, rowNum, rowNum, 3, 5, workbook);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("判定结果");
            headerRow.CreateCell(1, CellType.String).SetCellValue(orderModel.StrResult);
            MergedRegion(sheet, rowNum, rowNum, 1, 5, workbook);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("销售订单号");
            headerRow.CreateCell(1, CellType.String).SetCellValue(orderModel.SaleCode);
            MergedRegion(sheet, rowNum, rowNum, 1, 5, workbook);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("异常现象");
            headerRow.CreateCell(1, CellType.String).SetCellValue(orderModel.BadRemark);
            MergedRegion(sheet, rowNum, rowNum, 1, 5, workbook);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("备注");
            headerRow.CreateCell(1, CellType.String).SetCellValue(orderModel.Remark);
            MergedRegion(sheet, rowNum, rowNum, 1, 5, workbook);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("监装明细报表");
            MergedRegion(sheet, rowNum, rowNum, 0, 5, workbook);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("序号");
            headerRow.CreateCell(1, CellType.String).SetCellValue("检验项目");
            headerRow.CreateCell(3, CellType.String).SetCellValue("检验结果");
            headerRow.CreateCell(4, CellType.String).SetCellValue("判定");
            headerRow.CreateCell(5, CellType.String).SetCellValue("备注");
            MergedRegion(sheet, rowNum, rowNum, 1, 2, workbook);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });
        }

        /// <summary>
        /// 货柜七点检验表头
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheet"></param>
        /// <param name="rowNum"></param>
        /// <param name="orderModel"></param>
        private void GenerateSheetContainerCheckHeader(IWorkbook workbook, ISheet sheet, int rowNum, ContainerCheckOrderModel orderModel)
        {
            ICellStyle boldStyle = ExcelStyleUtils.GetExcelOQCStyle(workbook);
            IRow headerRow = sheet.CreateRow(rowNum);
            var saleCode = string.Empty;
            headerRow.CreateCell(0, CellType.String).SetCellValue("日期");
            headerRow.CreateCell(1, CellType.String).SetCellValue(orderModel.StrCreateTime);
            headerRow.CreateCell(2, CellType.String).SetCellValue("判定结果");
            headerRow.CreateCell(3, CellType.String).SetCellValue(orderModel.StrResult);
            headerRow.CreateCell(4, CellType.String).SetCellValue("柜型");
            headerRow.CreateCell(5, CellType.String).SetCellValue(orderModel.ContainerType);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("装柜编号+分组");
            headerRow.CreateCell(1, CellType.String).SetCellValue(orderModel.ContainerNumber);
            headerRow.CreateCell(2, CellType.String).SetCellValue("柜号");
            headerRow.CreateCell(3, CellType.String).SetCellValue(orderModel.ContainerCode);
            headerRow.CreateCell(4, CellType.String).SetCellValue("车架号/车牌号");
            headerRow.CreateCell(5, CellType.String).SetCellValue(orderModel.Vin);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("项目");
            headerRow.CreateCell(1, CellType.String).SetCellValue("内容");
            headerRow.CreateCell(5, CellType.String).SetCellValue("检查结果");
            MergedRegion(sheet, rowNum, rowNum, 1, 4, workbook);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });
        }

        /// <summary>
        /// 表尾
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheet"></param>
        /// <param name="rowNum"></param>
        /// <param name="orderModel"></param>
        private void GenerateSheetLSFooter(IWorkbook workbook, ISheet sheet, int rowNum, ContainerCheckOrderModel order)
        {
            ICellStyle boldStyle = ExcelStyleUtils.GetExcelOQCStyle(workbook);
            IRow headerRow = sheet.CreateRow(rowNum);
            var saleCode = string.Empty;
            headerRow.CreateCell(0, CellType.String).SetCellValue("检验员");
            headerRow.CreateCell(1, CellType.String).SetCellValue(order.CheckUser);
            headerRow.CreateCell(2, CellType.String).SetCellValue("保存期限");
            headerRow.CreateCell(3, CellType.String).SetCellValue(order.ShelfLife + "年");

            headerRow.CreateCell(4, CellType.String).SetCellValue("制订部门");
            headerRow.CreateCell(5, CellType.String).SetCellValue("品管部");
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });

            rowNum++;
            headerRow = sheet.CreateRow(rowNum);
            headerRow.CreateCell(0, CellType.String).SetCellValue("审核");
            headerRow.CreateCell(1, CellType.String).SetCellValue(order.ResponsibleUser);
            headerRow.CreateCell(2, CellType.String).SetCellValue("表单编号");
            headerRow.CreateCell(3, CellType.String).SetCellValue(order.TableCode);
            MergedRegion(sheet, rowNum, rowNum, 3, 5, workbook);
            headerRow.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });
        }

        /// <summary>
        /// 标题
        /// </summary>
        /// <param name="workbook"></param>
        /// <param name="sheet"></param>
        /// <param name="rowNum"></param>
        /// <param name="reportType"></param>
        /// <param name="samplingSchemeName"></param>
        private void GenerateExcelLSHeader(IWorkbook workbook, ISheet sheet, int rowNum, string headName)
        {
            ICellStyle boldStyle = ExcelStyleUtils.GetExcelHeaderOQCStyle(workbook);
            IRow headerRow1 = sheet.CreateRow(rowNum);
            headerRow1.CreateCell(0, CellType.String).SetCellValue(headName);
            MergedRegion(sheet, rowNum, rowNum, 0, 5, workbook);
            headerRow1.Height = 50 * 10;
            headerRow1.Cells.ForEach(cell =>
            {
                cell.CellStyle = boldStyle;
            });
        }

        private void MergedRegion(ISheet sheet, int firstRow, int lastRow, int firstCol, int lastCol, IWorkbook workbook)
        {
            var region = new NPOI.SS.Util.CellRangeAddress(firstRow, lastRow, firstCol, lastCol);
            sheet.AddMergedRegion(region);
            RegionUtil.SetBorderLeft(1, region, sheet);
            RegionUtil.SetBorderRight(1, region, sheet);
            RegionUtil.SetBorderTop(1, region, sheet);
            RegionUtil.SetBorderBottom(1, region, sheet);
        }

        /// <summary>
        /// 设置列宽
        /// </summary>
        /// <param name="sheet"></param>
        private void GenerateSheetSetColunmsWidth(ISheet sheet)
        {
            sheet.SetColumnWidth(0, 10 * 350);
            sheet.SetColumnWidth(1, 10 * 350);
            sheet.SetColumnWidth(2, 10 * 350);
            sheet.SetColumnWidth(3, 10 * 350);
            sheet.SetColumnWidth(4, 10 * 350);
            sheet.SetColumnWidth(5, 10 * 350);
        }
    }
}
